package com.lingjtx.auth.controller;


import com.lingjtx.auth.po.LoginConfirmPo;
import com.lingjtx.auth.po.SmsCodePo;
import com.lingjtx.auth.po.UpdatePswPo;
import com.lingjtx.auth.service.UserService;
import com.lingjtx.common.captcha.CaptchaType;
import com.lingjtx.common.captcha.NeedCaptcha;
import com.lingjtx.common.core.ResponseCode;
import com.lingjtx.common.core.ResponseResult;
import com.lingjtx.common.core.annotation.IgnoreLogin;
import com.lingjtx.common.core.constant.Const;
import com.lingjtx.common.core.constant.ResponseTip;
import com.lingjtx.common.core.exception.ParamCheckException;
import com.lingjtx.common.core.token.IgnoreType;
import com.lingjtx.common.core.token.LoginMode;
import com.lingjtx.common.core.token.UserVo;
import com.lingjtx.common.core.util.StringUtil;
import com.lingjtx.common.security.annotation.ApiLimited;
import com.lingjtx.common.security.model.LoginPo;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.Map;
import java.util.Objects;

/**
 * 用户中心
 */
@RestController
public class UserController {

    private final UserService userService;

    public UserController(UserService userService) {
        this.userService = userService;
    }

    /**
     * 发送短信验证码
     */
    @IgnoreLogin
    @ApiLimited(limited = true, count = 15)
    @NeedCaptcha(type = CaptchaType.CLICK_WORD)
    @PostMapping("send_sms_code")
    public ResponseResult<Void> sendSmsCode(@Valid @RequestBody SmsCodePo model) {
        String msg = userService.sendSmsCode(model.getIdentifier(), model.getSmsType());
        return ResponseResult.createBySuccess(msg);
    }

    /**
     * 账密登录
     */
    @IgnoreLogin(value = IgnoreType.LOGIN)
    @NeedCaptcha(type = CaptchaType.BLOCK_PUZZLE, nums = 3)
    @PostMapping("login_psw")
    public ResponseResult<UserVo> loginByPassword(@Valid @RequestBody LoginPo model) {
        UserVo user = userService.loginByPassword(model);
        if (Objects.nonNull(user)) {
            return ResponseResult.createBySuccess(user);
        }
        return ResponseResult.createByError(ResponseTip.RESPONSE_TIP_USERNAME_PASSWORD_ERROR);
    }

    /**
     * 短信验证码登录
     */
    @IgnoreLogin(value = IgnoreType.LOGIN, model = LoginMode.MOBILE)
    @PostMapping("login_sms")
    public ResponseResult<Object> loginBySms(@Valid @RequestBody LoginPo model) {
        return loginByOther(model);
    }

    /**
     * 邮箱验证码登录
     */
    @IgnoreLogin(value = IgnoreType.LOGIN, model = LoginMode.EMAIL)
    @PostMapping("login_email_sms")
    public ResponseResult<Object> loginByEmailSms(@Valid @RequestBody LoginPo model) {
        return loginByOther(model);
    }


    /**
     * 人脸登录
     */
    @IgnoreLogin(value = IgnoreType.LOGIN, model = LoginMode.FACE)
    @PostMapping("login_face")
    public ResponseResult<Object> loginByFace(@Valid @RequestBody LoginPo model) {
        return loginByOther(model);
    }

    /**
     * 微信登录
     */
    @IgnoreLogin(value = IgnoreType.LOGIN, model = LoginMode.WX_OPENID)
    @PostMapping("login_wx")
    public ResponseResult<Object> loginByWinxin(@Valid @RequestBody LoginPo model) {
        return loginByOther(model);
    }

    /**
     * 手机号码一键登录
     */
    @IgnoreLogin(value = IgnoreType.LOGIN, model = LoginMode.ONE_CLICK)
    @PostMapping("login_one_click")
    public ResponseResult<Object> loginByOneClick(@Valid @RequestBody LoginPo model) {
        return loginByOther(model);
    }

    /**
     * 刷新token
     */
    @ApiLimited(limited = true, count = 60)
    @IgnoreLogin(value = IgnoreType.LOGIN, model = LoginMode.REFRESH_TOKEN)
    @GetMapping("refresh_token")
    public ResponseResult<Object> refreshToken(LoginPo model, HttpServletRequest request) {
        // @RequestHeader(Const.AuthTokenMap.AUTHORIZATION 如果没有AUTHORIZATION值就会异常
        UserVo user = userService.refreshToken(request.getHeader(Const.AuthTokenMap.AUTHORIZATION), model);
        if (Objects.nonNull(user)) {
            return ResponseResult.createBySuccess(user);
        }
        return ResponseResult.createByError(ResponseCode.NOT_LOGIN, userService.getBaseWeixinOauthUrl());
    }

    /**
     * 退出登录
     */
    @IgnoreLogin(IgnoreType.LOGOUT)
    @GetMapping("logout")
    public ResponseResult<Void> logout() {
        return ResponseResult.createBySuccess("退出成功");
    }

    /**
     * 生成登录二维码链接
     */
    @IgnoreLogin
    @PostMapping("login_url")
    public ResponseResult<String> loginByUrl(@RequestBody LoginPo model) {
        String url = userService.loginByUrl(model);
        return ResponseResult.createBySuccessToString(url);
    }

    /**
     * 手机客户端扫码创建登录，根据手机端token创建pc端token
     */
    @PostMapping("login_confirm")
    public ResponseResult<Void> confirmLogin(@Valid @RequestBody LoginConfirmPo model) {
        boolean res = userService.confirmLogin(model);
        if (res) {
            return ResponseResult.createBySuccess("登录成功");
        }
        return ResponseResult.createByError("登录失败，请重新扫码登录");
    }

    /**
     * 每秒请求一次，查询扫码状态：0-未扫码；1-已扫码；2-确认登录；3-二维码无效
     */
    @IgnoreLogin
    @GetMapping("scan_status")
    public ResponseResult<Map<String, Integer>> scanStatus(LoginConfirmPo model) {
        Map<String, Integer> res = userService.scanStatus(model);
        return ResponseResult.createBySuccess(res);
    }

    /**
     * 确认登录之后，返回的登录信息
     */
    @IgnoreLogin(value = IgnoreType.LOGIN)
    @PostMapping("bizlogin")
    public ResponseResult<UserVo> bizlogin(@Valid @RequestBody LoginConfirmPo model) {
        UserVo user = userService.bizlogin(model);
        if (Objects.nonNull(user)) {
            return ResponseResult.createBySuccess(user);
        }
        return ResponseResult.createByError("二维码过期，请重新扫码登录");
    }

    /**
     * 获取用户信息
     */
    @GetMapping("get_user_info")
    public ResponseResult<Object> getUserInfo() {
        Object entity = userService.getUserInfo();
        return ResponseResult.createBySuccess(entity);
    }

    /**
     * 修改密码
     */
    @PostMapping("update_password")
    public ResponseResult<Void> updatePassword(@RequestBody UpdatePswPo model) {
        if (StringUtil.isEmpty(model.getOldPassword()) || StringUtil.isEmpty(model.getNewPassword())) {
            throw new ParamCheckException();
        }
        boolean res = userService.updatePassword(model);
        if (res) {
            return ResponseResult.createBySuccess(ResponseTip.RESPONSE_TIP_UPDATE);
        }
        return ResponseResult.createByError("密码验证错误");
    }

    /**
     * 绑定邮箱
     */
    @PostMapping("bound_email")
    public ResponseResult<Void> boundEmail(@RequestBody UpdatePswPo model) {
        boolean res = userService.boundEmail(model);
        if (res) {
            return ResponseResult.createBySuccess("激活链接已发送，请打开邮件确认链接");
        }
        return ResponseResult.createByError("请输入正确邮箱地址");
    }

    /**
     * 更改手机号码
     */
    @PostMapping("update_mobile")
    public ResponseResult<Void> updateMobile(@RequestBody UpdatePswPo model) {
        if (StringUtil.isEmpty(model.getMobile()) || StringUtil.isEmpty(model.getSmsCode())) {
            throw new ParamCheckException();
        }
        boolean res = userService.updateMobile(model);
        if (res) {
            return ResponseResult.createBySuccess(ResponseTip.RESPONSE_TIP_UPDATE);
        }
        return ResponseResult.createByError(ResponseTip.RESPONSE_TIP_SMS_CODE_ERROR);
    }

    /**
     * 更新用户信息
     */
    @PostMapping("update_user_info")
    public ResponseResult<Void> updateUserInfo(@RequestBody Object model) {
        userService.updateUserInfo(model);
        return ResponseResult.createBySuccess(ResponseTip.RESPONSE_TIP_UPDATE);
    }

    /**
     * 注销账号
     */
    @PostMapping("delete_account")
    public ResponseResult<Void> deleteAccount(@RequestBody LoginPo model) {
        if (StringUtil.isEmpty(model.getIdentifier()) || StringUtil.isEmpty(model.getSmsCode())) {
            throw new ParamCheckException();
        }
        boolean res = userService.deleteAccount(model);
        if (res) {
            return ResponseResult.createBySuccess("注销成功");
        }
        return ResponseResult.createByError("账号验证不通过，请输入重新获取验证码");
    }

    private ResponseResult<Object> loginByOther(LoginPo model) {
        UserVo user = userService.loginByOther(model);
        if (Objects.nonNull(user)) {
            return ResponseResult.createBySuccess(user);
        }
        return ResponseResult.createByError(ResponseCode.NOT_LOGIN, userService.getBaseWeixinOauthUrl());
    }
}
